package org.example.queue;

import org.junit.Test;

import java.util.Deque;
import java.util.LinkedList;

/**
 * Java SE 双链表队列
 * 1、LinkedList 实现了 List 和 Deque 接口，所以是一种双链表结构，可以当作堆栈、队列、双向队列使用
 * 2、一个双向列表的每一个元素都有三个整数值：元素、向后的节点链接、向前的节点链接
 * 3、LinkedList不是线程安全的，所以可以使用如下方式保证线程安全。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2021/8/1 15:29
 */
public class LinkedListTest {

    /**
     * 添加（Insert） 元素的动作，会有两种方式： add(e) 和offer(e) 。如果调用add(e)
     * 方法时，添加失败，则会抛异常，而如果调用的是offer(e)方法失败时，则会返回false 。
     * offer方法用于异常是正常的情况下使用，比如在有界队列中，优先使用offer方法。假如队列
     * 满了，不能添加元素，offer方法返回false，这样我们就知道是队列满了，而不是去handle运
     * 行时抛出的异常。
     */
    @Test
    public void testLinkedList1() {
        Deque<String> linkedList = new LinkedList<String>();
        linkedList.add("1");
        linkedList.add("2");
        linkedList.add(null);
        linkedList.addFirst("a");
        linkedList.addFirst("b");
        linkedList.addLast("!");

        System.out.println(linkedList);//[b, a, 1, 2, null, !]

        linkedList.removeFirst();
        System.out.println(linkedList);//[a, 1, 2, null, !]
        while (linkedList.size() > 0) {
            linkedList.remove();
        }
        System.out.println(linkedList);//[]
    }

    /**
     * 移除（Remove）元素的动作，队列为空时，remove方法抛异常，而poll返回null。如
     * 果移除头部的元素成功，则返回移除的元素。
     * （3）同理，检测（Examine）元素的动作，返回头部元素（最开始加入的元素），但不删除元素，
     * 如果队列为空，则element()方法抛异常，而peek()返回false。
     */
    @Test
    public void testLinkedList2() {
        Deque<String> linkedList = new LinkedList<String>();
        linkedList.offer("1");
        linkedList.offer("2");
        linkedList.offer(null);
        linkedList.offerFirst("a");
        linkedList.offerFirst("b");
        linkedList.offerLast("!");

        System.out.println(linkedList);//[b, a, 1, 2, null, !]

        linkedList.pollLast();
        System.out.println(linkedList);//[b, a, 1, 2, null]
        while (linkedList.size() > 0) {
            linkedList.poll();
        }
        System.out.println(linkedList);//[]
    }

}
